/***************************************************************************
 *   Copyright (C) 2006 by Grzegorz Latarowski                             *
 *   g.latarowski@gmail.com                                                *
 *                                                                         *
 *   Project: AutoStop (kodowa nazwa do zmiany)                            *
 *                                                                         *
 ***************************************************************************/



#include "mainwindow.h"
#include "filterdialog.h"
#include "baseheader.h"
#include "gmovieplayer.h"

#include <stdlib.h>

// using std::string;


// ===========================================================================
//                              MainWindow
// ===========================================================================


// ------------------------------ MainWindow() -------------------------------
MainWindow::MainWindow() : QMainWindow()
{
    ui.setupUi(this);
    
    _model = new QSqlTableModel;
    _fastFilterModel = new GlobalSortFilterProxyModel;
    _globalSortModel = new QSortFilterProxyModel;
    _filter = new Filter;

        // ustaw parametry tabeli 
    ui.tableView->horizontalHeader()->setDefaultAlignment(Qt::AlignLeft);
    ui.tableView->horizontalHeader()->setSortIndicator(0, Qt::AscendingOrder);
    ui.tableView->horizontalHeader()->setSortIndicatorShown(true);
    QPalette tableViewPalette;
    tableViewPalette.setColor(QPalette::AlternateBase, QColor(238, 246, 255));
    ui.tableView->setPalette(tableViewPalette);
    ui.tableView->setItemDelegate(new QSqlRelationalDelegate(ui.tableView));
    
        // edytuj pasek zadań 
    QToolBar *toolBar = new QToolBar();
    toolBar->addAction(ui.newAction);
    toolBar->addAction(ui.openAction);
    toolBar->addAction(ui.exportAction);
    toolBar->addSeparator();
    toolBar->addAction(ui.adjustColumnAction);
    toolBar->addAction(ui.removeSelectedRowsAction);
    toolBar->addSeparator();
    toolBar->addAction(ui.filterAction);
    toolBar->addAction(ui.clearFilterAction);
    addToolBar(toolBar);
    
        // szybki filtr 
    fastFilterToolBar = new QToolBar();
    fastFilterLineEdit = new QLineEdit();
    fastFilterLineEdit->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum);
    fastFilterLineEdit->setFixedHeight(24);
    clearFastFilterAction = new QAction(QIcon(":/images/clear_left.png"),
                                        QString::fromUtf8("Wyczyść szybki filtr"), this);
    QLabel *fastFilterLabel = new QLabel(" &Szybki filtr ");
    fastFilterLabel->setBuddy(fastFilterLineEdit);
    fastFilterToolBar->addWidget(fastFilterLabel);
    fastFilterToolBar->addWidget(fastFilterLineEdit);
    fastFilterToolBar->addAction(clearFastFilterAction);
    addToolBar(fastFilterToolBar);
    
    connect(clearFastFilterAction, SIGNAL(triggered()),
            this, SLOT(clearFastFilterLineEdit()));
    connect(fastFilterLineEdit, SIGNAL(editingFinished()),
            this, SLOT(fastFilterChanged()));
        
    connect(ui.newAction, SIGNAL(triggered()),
            this, SLOT(newBaseDialog()));
    connect(ui.openAction, SIGNAL(triggered()),
            this, SLOT(openBaseDialog()));
    connect(ui.exportAction, SIGNAL(triggered()),
            this, SLOT(exportBaseDialog()));
    connect(ui.removeSelectedRowsAction, SIGNAL(triggered()),
            this, SLOT(removeSelectedRows()));
    connect(ui.adjustColumnAction, SIGNAL(triggered()),
            this, SLOT(adjustColumns()));
    connect(ui.aboutAction, SIGNAL(triggered()), this, SLOT(about()));
    connect(ui.tableView->horizontalHeader(), SIGNAL(sectionClicked(int)),
            ui.tableView, SLOT(sortByColumn(int)));
    connect(ui.filterAction, SIGNAL(triggered()),
            this, SLOT(filterWizardDialog()));
    connect(ui.showFastFilterAction, SIGNAL(triggered(bool)),
            fastFilterToolBar, SLOT(setVisible(bool)));
    connect(ui.clearFilterAction, SIGNAL(triggered()),
            this, SLOT(clearFilter()));
    connect(this, SIGNAL(filtersEnabled(bool)),
            ui.clearFilterAction, SLOT(setEnabled(bool)));
    connect(ui.tableView, SIGNAL(doubleClicked(const QModelIndex &)),
            this, SLOT(startPlayback(const QModelIndex &)));
    connect(ui.tableView->horizontalHeader(), SIGNAL(sectionResized(int, int, int)),
            this, SLOT(saveColumnWidth(int, int, int)));
    
    connect(ui.tmpAction, SIGNAL(triggered()),
            this, SLOT(tmpSlot()));
    connect(ui.tmpAction2, SIGNAL(triggered()),
            this, SLOT(tmpSlot2()));
    
    
        // wyłącz akcje manipulowania widokiem póki nie ma wczytanych danych 
    setTableActionsDisabled(true);

        // zarządź modelami co by był porządek
    manageModels();
}
// ---------------------------------------------------------------------------


// --------------------------- closeEvent() ----------------------------------
void MainWindow::closeEvent(QCloseEvent *)
{
        // zamknij połączenie z bazą
    QSqlDatabase::removeDatabase("autostopEvents");
}
// ---------------------------------------------------------------------------


// --------------------------- openBaseDialog() ------------------------------
void MainWindow::openBaseDialog()
{ 
    QFileDialog openDialog(this, "Otwórz plik z bazą", ".", "Wszystkie pliki (*)");
    openDialog.setAcceptMode(QFileDialog::AcceptOpen);
    openDialog.setLabelText(QFileDialog::LookIn, QString::fromUtf8("Szukaj w:"));
    openDialog.setLabelText(QFileDialog::FileName, QString::fromUtf8("Lokalizacja"));
    openDialog.setLabelText(QFileDialog::FileType, QString::fromUtf8("Filtr"));
    openDialog.setLabelText(QFileDialog::Accept, QString::fromUtf8("&Zapisz"));
    openDialog.setLabelText(QFileDialog::Reject, QString::fromUtf8("&Anuluj"));
    QObjectList objectList = openDialog.children();
    QToolButton *toolButton = (QToolButton *)objectList.at(14);
    toolButton->setToolTip(QString::fromUtf8("Wstecz"));
    toolButton = (QToolButton *)objectList.at(15);
    toolButton->setToolTip(QString::fromUtf8("W górę"));
    toolButton = (QToolButton *)objectList.at(16);
    toolButton->setToolTip(QString::fromUtf8("Utwórz nowy folder"));
    toolButton = (QToolButton *)objectList.at(17);
    toolButton->setToolTip(QString::fromUtf8("Lista"));
    toolButton = (QToolButton *)objectList.at(18);
    toolButton->setToolTip(QString::fromUtf8("Szczegóły"));
    
            // uruchom okienko 
    if(openDialog.exec()) {
        QString fileName = openDialog.selectedFiles().takeFirst();
            
            // użytkownik wcisnął cancel
        if(fileName.isEmpty()) {
            return;
        }
            // sprawdź czy plik w porządku i czy da się otworzyć i zapiszywać
        QFileInfo fileInfo(fileName);
        if(!fileInfo.isFile() || !fileInfo.isReadable() || !fileInfo.isWritable()) {
            return;
        }
    
        // wszystko poszło OK
    
            // wyczyść baze
        clear();
    
            // otwórz baze 
        openBase(fileName);
    }
}
// ---------------------------------------------------------------------------


// ----------------------------- openBase() ----------------------------------
void MainWindow::openBase(QString fileName)
{
    _baseFileName = fileName;
    
        // otwórz/utwórz baze 
    if(createConnection(_baseFileName)) {
        readBase();
            // utwórz menu ustawiania widoku tabeli
        createSetupViewActionsList();
            // uruchom niedostępne akcje
        setTableActionsEnabled(true);
            // skonfiguruj modele
        manageModels();
            // zapisz szerokości kolumn widoku tabeli
            // zapełniając tym samym liste
        saveColumnsWidth();
            // dopasuj szerokości kolumn do zawartości
        adjustColumns();
    }
    
    Benchmark("sql benchmark", true);
    
    QSqlQuery query;
    query.exec("SELECT * FROM autostop");
        // jeśli nie udało się odnaleźć rekordów to wypad 
    if(!query.isSelect()) {
        return;
    }
            // wyszukaj pierwszy rekord w zaznaczeniu
    quint32 recordCounter = 1;
    query.first();
    while(query.next()) {
        recordCounter++;
    }
    statusBar()->showMessage(QString("Wczytano %1 rekordów.").arg(recordCounter), 10000);
    Benchmark("sql stop");
}
// ---------------------------------------------------------------------------


// --------------------------- newBaseDialog() -------------------------------
void MainWindow::newBaseDialog()
{
    QFileDialog newDialog(this, "Utwórz plik z nową bazą", ".", "Wszystkie pliki (*)");
    newDialog.setAcceptMode(QFileDialog::AcceptSave);
    newDialog.setLabelText(QFileDialog::LookIn, QString::fromUtf8("Szukaj w:"));
    newDialog.setLabelText(QFileDialog::FileName, QString::fromUtf8("Lokalizacja"));
    newDialog.setLabelText(QFileDialog::FileType, QString::fromUtf8("Filtr"));
    newDialog.setLabelText(QFileDialog::Accept, QString::fromUtf8("&Zapisz"));
    newDialog.setLabelText(QFileDialog::Reject, QString::fromUtf8("&Anuluj"));
    QObjectList objectList = newDialog.children();
    QToolButton *toolButton = (QToolButton *)objectList.at(14);
    toolButton->setToolTip(QString::fromUtf8("Wstecz"));
    toolButton = (QToolButton *)objectList.at(15);
    toolButton->setToolTip(QString::fromUtf8("W górę"));
    toolButton = (QToolButton *)objectList.at(16);
    toolButton->setToolTip(QString::fromUtf8("Utwórz nowy folder"));
    toolButton = (QToolButton *)objectList.at(17);
    toolButton->setToolTip(QString::fromUtf8("Lista"));
    toolButton = (QToolButton *)objectList.at(18);
    toolButton->setToolTip(QString::fromUtf8("Szczegóły"));
    
            // uruchom okienko 
    if(newDialog.exec()) {
        QString fileName = newDialog.selectedFiles().takeFirst();
            
            // użytkownik wcisnął cancel
        if(fileName.isEmpty()) {
            return;
        }
        
            // sprawdź czy plik w porządku i czy da się otworzyć i zapiszywać
        QFile file(fileName);
        QFileInfo fileInfo(file);
        
            // sprawdź czy nie jest katalogiem
        if(fileInfo.isDir()) {
            QMessageBox::about(this, QString::fromUtf8("Błąd AutoBazy"),
                               QString::fromUtf8("<p>Wybrany element nie jest plikiem.</p>"));
            return;
        }
        
            // jeśli plik istnieje już to go usuń
        if(fileInfo.exists()) {
            if(!file.remove()) {
                    // a jeśli nie można to wypad
                QMessageBox::about(this,
                                   QString::fromUtf8("Błąd AutoBazy"),
                                   QString("<p>Brak dostępu do %1</p>").arg(fileName)
                                  );
                return;
            }
        }
    
        // wszystko poszło OK
    
            // wyczyść baze
        clear();
    
            // utwórz baze 
        newBase(fileName);
    }
}
// ---------------------------------------------------------------------------


// ------------------------------ newBase() ----------------------------------
void MainWindow::newBase(QString fileName)
{
        // jeśli plik fileName nie istnieje to podczas procedury łączenia
        // z bazą wywoływanej prez openBase() zostanie utworzony plik
        // w którym zapisane będą tabele
    openBase(fileName);
}
// ---------------------------------------------------------------------------

 
// ---------------------------- readBase() -----------------------------------
void MainWindow::readBase()
{
        // utwórz kwestionariusz 
    QSqlQuery query;
    
        // utwórz nowy model 
    _model = new QSqlTableModel;
    
        // zaczytaj główną tabelę z pomiarami 
    _model->setTable("autostop");
    
        // zaczytaj tabele z nagłówkami 
    QSqlTableModel *header = new QSqlTableModel;
    header->setTable("header");
    header->select();
        // ustaw nagłówki do modelu 
    for(int i = 0; i < header->rowCount(); i++) {
        QModelIndex index = header->index(i, 1);
        _model->setHeaderData(i, Qt::Horizontal, header->data(index).toString());
    }
       
        // zapnij model 
    _model->select();    
}
// ---------------------------------------------------------------------------


// -------------------------------- about() ----------------------------------
void MainWindow::about()
{
    QMessageBox::about(this, QString::fromUtf8("O programie"),
                       QString::fromUtf8("<p>W Szczebrzeszynie chrząszcz brzmi w trzcinie.</p>"));
}
// ---------------------------------------------------------------------------


// ----------------------------- removeSelectedRows() ------------------------
void MainWindow::removeSelectedRows()
{   
            // odszukaj zaznaczone elementy 
    QItemSelectionModel *selectionModel = ui.tableView->selectionModel();
    QModelIndexList indexes = selectionModel->selectedIndexes();
    QModelIndex index;
    
        // jeśli żaden nie jest zaznaczony to wyjdź
    if(indexes.isEmpty()) return;
    
        // końcówka 'y' gdy tylko jeden rekord do usunięcia
    QString suffix1 = "y";
    QString suffix2 = "";
        // jeśli więcej to 'e'
    if(indexes.size() > ui.tableView->model()->columnCount()) {
        suffix1 = "e";
        suffix2 = "y";
    }
    
    QMessageBox mb(QString::fromUtf8("AutoBase"),
                   QString::fromUtf8("Czy na pewno chcesz trwale usunąć "
                           "zaznaczon%1 rekord%2?").arg(suffix1).arg(suffix2),
                   QMessageBox::Question,
                   QMessageBox::Yes,
                   QMessageBox::No | QMessageBox::Escape | QMessageBox::Default,
                   QMessageBox::NoButton);
    mb.setButtonText(QMessageBox::Yes, QString::fromUtf8("&Tak"));
    mb.setButtonText(QMessageBox::No, QString::fromUtf8("&Nie"));
    if(mb.exec() == QMessageBox::Yes) {
        // say YES
            // usuń rekordy 
        int row, tmp;
        QList<int> rows; // lista wierszy do usunięcia 
        bool append;
        
            // stwórz liste wierszy do usunięcia 
        foreach(index, indexes) {
                // jakby co to trzeba dodać do listy 
            append = true;
            row = index.row();
                // sprawdź czy nie ma juz odczytanego wiersza na liście
            foreach(tmp, rows) {
                    // jeśli już jest to oznacz żeby nie dodawać
                if(row == tmp) append = false;
            }
                // dodaj wiersz do listy jeśli jeszcze nie ma 
            if(append == true) rows << row;
        }
            // posortuj listę wierszy do usunięcia 
        qSort(rows.begin(), rows.end());
    
            // wyczyść zaznaczenie 
        selectionModel->clear();
    
            // pobierz model który jest aktualnie wyświetlany przez tabele
        QAbstractItemModel *removeModel = ui.tableView->model();
            // usuwaj wiersze od końca aby nie było nieporozumień    
        while(!rows.isEmpty()) {
                // usuń z  modelu
            removeModel->removeRows(rows.takeLast(), 1);
            
            //! TODO: usuwanie plików ze zdarzeniem z bazy
        }
    }
}
// ---------------------------------------------------------------------------


// ------------------------ clearFilter() ------------------------------------
void MainWindow::clearFilter()
{
    delete _filter;
    _filter = new Filter;

        // ustaw modele odpowiednio i wszystko tam jeszcze
    manageModels();
}
// ---------------------------------------------------------------------------


// -------------------------- adjustColumns() --------------------------------
void MainWindow::adjustColumns()
{
    ui.tableView->resizeColumnsToContents();
    
        // poszeż je troche bo za wąsko
    for(int i = 0; i < _model->columnCount(); i++) {
        ui.tableView->setColumnWidth(i, ui.tableView->columnWidth(i) + 20);
    }
}
// ---------------------------------------------------------------------------


// ---------------------------- adjustRows() ---------------------------------
void MainWindow::adjustRows()
{
        // dopasuj pierwszy wiersz a potem reszte do niego
    ui.tableView->resizeRowToContents(0);
    int height = ui.tableView->rowHeight(0);
    for(int i = 1; i < _model->rowCount(); i++) {
        ui.tableView->setRowHeight(i, height);
    }
}
// ---------------------------------------------------------------------------


// -------------------------- exportBaseDialog() -----------------------------
void MainWindow::exportBaseDialog()
{
        // utwórz okienko dialogowe do pobierania nazwy pliku
        // wszystko po polsku 
    QFileDialog saveDialog(this, "Eksportuj plik", ".", "Pliki tekstowe (*.csv)");
    saveDialog.setAcceptMode(QFileDialog::AcceptSave);
    saveDialog.setLabelText(QFileDialog::LookIn, QString::fromUtf8("Szukaj w:"));
    saveDialog.setLabelText(QFileDialog::FileName, QString::fromUtf8("Lokalizacja"));
    saveDialog.setLabelText(QFileDialog::FileType, QString::fromUtf8("Filtr"));
    saveDialog.setLabelText(QFileDialog::Accept, QString::fromUtf8("&Zapisz"));
    saveDialog.setLabelText(QFileDialog::Reject, QString::fromUtf8("&Anuluj"));
    QObjectList objectList = saveDialog.children();
    QToolButton *toolButton = (QToolButton *)objectList.at(14);
    toolButton->setToolTip(QString::fromUtf8("Wstecz"));
    toolButton = (QToolButton *)objectList.at(15);
    toolButton->setToolTip(QString::fromUtf8("W górę"));
    toolButton = (QToolButton *)objectList.at(16);
    toolButton->setToolTip(QString::fromUtf8("Utwórz nowy folder"));
    toolButton = (QToolButton *)objectList.at(17);
    toolButton->setToolTip(QString::fromUtf8("Lista"));
    toolButton = (QToolButton *)objectList.at(18);
    toolButton->setToolTip(QString::fromUtf8("Szczegóły"));
    
        // uruchom okienko 
    if(saveDialog.exec()) {
        QString fileName = saveDialog.selectedFiles().takeFirst();
        exportBase(fileName, true);
    }
}
// ---------------------------------------------------------------------------


// ------------------------------ exportBase() -------------------------------
void MainWindow::exportBase(QString fileName, bool header)
{
        // jeśli nie ma rozszerzenia 'csv' to je dodaj 
    QFileInfo fileInfo(fileName);
    if(fileInfo.suffix() != "csv") {
        fileName.append(".csv");
    }
    
    QModelIndex index;
    QFile file(fileName);
    if(!file.open(QIODevice::WriteOnly | QIODevice::Text)) {
        return;
    }
    
    QTextStream out(&file);
    
        // jeśli dołączyć nagłówek do dawaj
    if(header == true) {
            // zaczytaj nagłówek 
        QSqlTableModel *header = new QSqlTableModel;
        header->setTable("header");
        header->select();
        for(int i = 0; i < header->rowCount() - 1; i++) {
            if(!ui.tableView->isColumnHidden(i)) {
                QModelIndex index = header->index(i, 1);
                out << "\"" << header->data(index).toString() << "\",";
            }
        }
            // a teraz dopisz ostatni bez przecinka 
        int i = header->rowCount() - 1;
        if(!ui.tableView->isColumnHidden(i)) {
            QModelIndex index = header->index(i, 1);
            out << "\"" << header->data(index).toString() << "\"";
        }
        out << endl;
    }
    
        // pobierz model który jest aktualnie wyświetlany przez tabele
    QAbstractItemModel *exportModel = ui.tableView->model();
    
    for(int i = 0; i < exportModel->rowCount(); i++) {
        for(int j = 0; j < exportModel->columnCount() - 1; j++) {
            if(!ui.tableView->isColumnHidden(j)) {
                index = exportModel->index(i, j);
                out << "\"" << exportModel->data(index).toString() << "\",";
            }
        }
            // ostania kolumna bez separatora 
        int j = exportModel->columnCount() - 1;
        if(!ui.tableView->isColumnHidden(j)) {
            index = exportModel->index(i, j);
            out << "\"" << exportModel->data(index).toString() << "\"";
        }
        out << endl;
    }
    out << endl;
}
// ---------------------------------------------------------------------------


// ----------------------------- contextMenuEvent() --------------------------
void MainWindow::contextMenuEvent(QContextMenuEvent */*event*/)
{
//     QMenu menu(this);
//     menu.addAction(ui.adjustColumnAction);
//     menu.addAction(ui.removeSelectedRowsAction);
//     menu.exec(event->globalPos());
}
// ---------------------------------------------------------------------------


// --------------------------- hideShowColumn() ------------------------------
void MainWindow::hideShowColumn(bool)
{
    // Jeśli wyswietlić kolumny (show) to wyświetl wszystkie te
    // których akcje są zaznaczone, jeśli schować to ukryj wszystkie 
    // których akcje są odznaczone. Może brzydko ale mało roboty. 
    for(int i = 0; i < _setupViewActionsList.size(); i++) {
        if(_setupViewActionsList[i]->isChecked()) {
            ui.tableView->showColumn(i);
        } else {
            ui.tableView->hideColumn(i);
        }
    }
}
// ---------------------------------------------------------------------------


// --------------------------- createSetupViewActionsList() ------------------
void MainWindow::createSetupViewActionsList()
{
            // utwórz akcje ustawiania widoku tabeli 
    QSqlTableModel *header = new QSqlTableModel;
    header->setTable("header");
    header->select();
    for(int i = 0; i < header->rowCount(); i++) {
        QModelIndex index = header->index(i, 1);
        QAction *action = new QAction(header->data(index).toString(), this);
        _setupViewActionsList << action;
        _setupViewActionsList[i]->setCheckable(true);
        _setupViewActionsList[i]->setChecked(true);
        ui.setupViewMenu->addAction(_setupViewActionsList[i]);
        connect(_setupViewActionsList[i], SIGNAL(triggered(bool)),
                this, SLOT(hideShowColumn(bool)));
    } 
}
// ---------------------------------------------------------------------------


// --------------------------- clearSetupViewActionsList() -------------------
void MainWindow::clearSetupViewActionsList()
{
        // najpierw odłącz akcje
    while(!_setupViewActionsList.isEmpty()) {
        QAction *action = _setupViewActionsList.takeLast();
        disconnect(action, SIGNAL(triggered(bool)),
                   this, SLOT(hideShowColumn(bool)));
        delete action;
    }
        // wyczyść menu akcji
    ui.setupViewMenu->clear();
        // wyczyść listę akcji
    _setupViewActionsList.clear();
}
// ---------------------------------------------------------------------------


// ---------------------------- setTableActionsEnabled() ---------------------
void MainWindow::setTableActionsEnabled(bool b)
{
    ui.removeSelectedRowsAction->setEnabled(b);
    ui.filterAction->setEnabled(b);
    ui.exportAction->setEnabled(b);
    ui.clearFilterAction->setEnabled(b);
    ui.adjustColumnAction->setEnabled(b);
    
    manageModels();
}
// ---------------------------------------------------------------------------


// --------------------------- setTableActionsDisabled() ---------------------
void MainWindow::setTableActionsDisabled(bool b)
{
    ui.removeSelectedRowsAction->setDisabled(b);
    ui.filterAction->setDisabled(b);
    ui.exportAction->setDisabled(b);
    ui.clearFilterAction->setDisabled(b);
    ui.adjustColumnAction->setDisabled(b);
    
    manageModels();
}
// ---------------------------------------------------------------------------


// ---------------------------- filterWizardDialog() -------------------------
void MainWindow::filterWizardDialog()
{    
    FilterWizardDialog filterWizardDialog(this);
    
        // uruchom okienko     
    if(filterWizardDialog.exec()) {
            // ustaw nowy filtr w programie
        delete _filter;
        _filter = filterWizardDialog.filter();
        manageModels();
    }
}
// ---------------------------------------------------------------------------


// -------------------------- clearFastFilterLineEdit() ----------------------
void MainWindow::clearFastFilterLineEdit()
{
    fastFilterLineEdit->clear();
    _fastFilterModel->setFilterRegExp(QRegExp());
    _filter->setFilterRegExp(QRegExp());
}
// ---------------------------------------------------------------------------


// ---------------------------- fastFilterChanged() --------------------------
void MainWindow::fastFilterChanged()
{
    if(fastFilterLineEdit->text().isEmpty()) {
        return;
    }
    
    QString regExp = "";
    regExp.append(fastFilterLineEdit->text());
    _fastFilterModel->setFilterRegExp(QRegExp(regExp, Qt::CaseInsensitive));
    
    _filter->setFilterRegExp(QRegExp());
}
// ---------------------------------------------------------------------------


// -------------------------------- saveColumnsWidth() -----------------------
void MainWindow::saveColumnsWidth()
{
    _columnsWidthList.clear();
    for(int i = 0; i < _model->columnCount(); i++) {
        _columnsWidthList << ui.tableView->columnWidth(i);
    }
}
// ---------------------------------------------------------------------------


// ---------------------------- saveColumnWidth() ----------------------------
void MainWindow::saveColumnWidth(int logicalIndex, int, int newSize)
{
        // sprawdź czy ustawiana kolumna jest już na liście
    if(_columnsWidthList.isEmpty() && (_columnsWidthList.size() < logicalIndex)) {
            // nie ma to h'asta la Vista
        return;
    } else {
        // jest to ją zapnij
        _columnsWidthList[logicalIndex] = newSize;
    }
}
// ---------------------------------------------------------------------------


// ------------------------------ restoreColumnsWidth() ----------------------
void MainWindow::restoreColumnsWidth()
{
    for(int i = 0; i < _columnsWidthList.size(); i++) {
        ui.tableView->setColumnWidth(i, _columnsWidthList[i]);
    }
}
// ---------------------------------------------------------------------------


// -------------------------------- clear() ----------------------------------
void MainWindow::clear() 
{
        // wyczyść model
    _model->clear();
    delete _model;
    _model = new QSqlTableModel;
    
        // wczyść akcje ustawiania widoku tabeli
    clearSetupViewActionsList();
    
        // zablokuj akcje obsługi tabeli
    setTableActionsDisabled(true);
    
    delete _filter;
    _filter = new Filter;
    
        // przypisz odpowiedni model do tabeli, w tym przypadku 'model'
    manageModels();
}
// ---------------------------------------------------------------------------


// ------------------------------- manageModels() ----------------------------
void MainWindow::manageModels()
{        
    // Następny wskazuje na poprzedni. Ostani do tabeli.
    
        // najpierwej model sortujący i globalFilter
    _globalSortModel->setSourceModel(_model);
    _fastFilterModel->setSourceModel(_globalSortModel);
    _filter->setSourceModel(_fastFilterModel);
    ui.tableView->setModel(_filter);
    
        // pochowaj odpowiednie kolumny po odświerzeniu widoku
    hideShowColumn();
    emit filtersEnabled(true);
        // przywróć też należytą szerokość kolumn
    restoreColumnsWidth();
}
// ---------------------------------------------------------------------------


// ----------------------------  updateBase() --------------------------------
void MainWindow::updateBase()
{

}
// ---------------------------------------------------------------------------


// ----------------------------  insertRecord() ------------------------------
void MainWindow::insertRecord(QString fileName)
{
    static int counter;

        // dodaj wiersz
    int row = _model->rowCount();
    _model->insertRows(row, 1);
        // id dodaje się automatycznie
    QString description = QString("Numer dodania %1. Dane z pliku %2")
            .arg(counter++)
            .arg(fileName);
    QDateTime dateTime = QDateTime::currentDateTime();
    _model->setData(_model->index(row, 1), QVariant(dateTime));
    _model->setData(_model->index(row, 2), QVariant(description));

        // zatwierdź zmiany
    _model->submitAll();

    manageModels();
    
    // wpisz pliku do bazy

        // odnajdź id nadane ostatniemu pomiarowi
    int id = _model->data(_model->index(row, 0)).toInt();
        // zaczytaj plik
    QFile file(fileName);
    if (!file.open(QIODevice::ReadOnly)) {
        return;
    }
    QByteArray fileData = file.readAll();

    qDebug() << "size " << fileData.size();
        // dodaj do tabeli z plikami
    QSqlQuery query;
    query.prepare("INSERT INTO events (id, event) "
            "VALUES (?, ?)");
    query.addBindValue(id);
    query.addBindValue(fileData, QSql::In | QSql::Binary);
    query.exec();

    // done
    qDebug() << "done";
}
// ---------------------------------------------------------------------------


// ------------------------------  startPlayback() ---------------------------
void MainWindow::startPlayback(const QModelIndex & index)
{
    
        // otwórz/utwórz katalog tymczasowy
    QDir tmpDir;
    tmpDir.mkpath("tmp");
    tmpDir.setPath("tmp");
    
    // utwórz nazwe pliku tymczasowego
        // przyrostek w celu uniknięcia powtarzających się nazw
    static int i;
        // kombinuj nazwe pliku
    QDateTime dateTime = QDateTime::currentDateTime();
    QString movieFileName;
    movieFileName.append(dateTime.toString("yyMMddhhmmss")).append(QString("%1").arg(i)).append(".mng");
    i++;
    
    QFileInfo movieFileInfo(tmpDir, movieFileName);
    
        // otwórz plik do zapisu
    QFile file(movieFileInfo.absoluteFilePath());
    if(!file.open(QIODevice::WriteOnly)) {
        return;
    }
    
        // wyszukaj rekord w tabeli plików o odpowiednim indexie
    QSqlQuery query;
        // arg - wiersze numerowane od zera a indeksy od 1
    QString statement = QString("SELECT event FROM events WHERE id = %1")
            .arg(index.row()+1);
    query.exec(statement);
        // jeśli udało się odnaleźć rekord
    if(query.isSelect()) {
            // wyszukaj pierwszy rekord w zaznaczeniu
        query.first();
            // zaczytaj go do bufora
        QByteArray fileBuffer = query.value(0).toByteArray();
            // zapisz cały bufor do pliku
        file.write(fileBuffer);
        file.close();

        GMoviePlayer *moviePlayer = new GMoviePlayer(movieFileInfo.absoluteFilePath());
        moviePlayer->exec();
    }
}
// ---------------------------------------------------------------------------


// ---------------------------------------------------------------------------
void MainWindow::tmpSlot()
{
    QString fileName = "mov1.mng";
//     GMoviePlayer *moviePlayer = new GMoviePlayer(fileName);
    GMoviePlayer *moviePlayer = new GMoviePlayer();
    moviePlayer->exec();
}
// ---------------------------------------------------------------------------


// ---------------------------------------------------------------------------
void MainWindow::tmpSlot2()
{
    QFileDialog openDialog(this, "Wybierz plik z filmem", ".", "Pliki filmów (*.mng)");
    openDialog.setAcceptMode(QFileDialog::AcceptOpen);
    openDialog.setLabelText(QFileDialog::LookIn, QString::fromUtf8("Szukaj w:"));
    openDialog.setLabelText(QFileDialog::FileName, QString::fromUtf8("Lokalizacja"));
    openDialog.setLabelText(QFileDialog::FileType, QString::fromUtf8("Filtr"));
    openDialog.setLabelText(QFileDialog::Accept, QString::fromUtf8("&Zapisz"));
    openDialog.setLabelText(QFileDialog::Reject, QString::fromUtf8("&Anuluj"));
    QObjectList objectList = openDialog.children();
    QToolButton *toolButton = (QToolButton *)objectList.at(14);
    toolButton->setToolTip(QString::fromUtf8("Wstecz"));
    toolButton = (QToolButton *)objectList.at(15);
    toolButton->setToolTip(QString::fromUtf8("W górę"));
    toolButton = (QToolButton *)objectList.at(16);
    toolButton->setToolTip(QString::fromUtf8("Utwórz nowy folder"));
    toolButton = (QToolButton *)objectList.at(17);
    toolButton->setToolTip(QString::fromUtf8("Lista"));
    toolButton = (QToolButton *)objectList.at(18);
    toolButton->setToolTip(QString::fromUtf8("Szczegóły"));
    
            // uruchom okienko 
    if(openDialog.exec()) {
        QString fileName = openDialog.selectedFiles().takeFirst();
            
            // użytkownik wcisnął cancel
        if(fileName.isEmpty()) {
            return;
        }
            // sprawdź czy plik w porządku i czy da się otworzyć
        QFileInfo fileInfo(fileName);
        if(!fileInfo.isFile() || !fileInfo.isReadable()) {
            return;
        }
    
        // wszystko poszło OK dodaj go do bazy

        insertRecord(fileName);
        
    }

    
}
// ---------------------------------------------------------------------------



// ===========================================================================
//                                  Functions
// ===========================================================================


// -------------------------------  CPULoad() --------------------------------
void CPULoad(unsigned int seconds)
{
    QDateTime before = QDateTime::currentDateTime();
    QDateTime after;
    unsigned int diff;
    double a = 13;
    double b = 11;
    double c = 1;
    
    do {
        c = (double)a/b*c;
        after = QDateTime::currentDateTime();
        diff = after.toTime_t() - before.toTime_t();
    } while(diff < seconds);
}
// ---------------------------------------------------------------------------


// ------------------------------  Benchmark() -------------------------------
void Benchmark(QString text, bool start)
{
    static QDateTime before;
    QDateTime after;
    unsigned int diff;
    
    if(start) {
        before = QDateTime::currentDateTime();
    } 
    
    after = QDateTime::currentDateTime();
    diff = after.toTime_t() - before.toTime_t();
    qDebug() << qPrintable(text) << " " << diff;
}
// ---------------------------------------------------------------------------



